/*
 * Copyright (c) 2016. @huishenghuo.inf,Co,Limitid.
 */

package com.xiaoq.user.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaoq.apis.interpreter.IInterpreterApi;
import com.xiaoq.apis.order.IUserCouponApi;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.RestException;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.oauth2.entity.OAuth2TokenEntity;
import com.xiaoq.oauth2.service.OAuth2Service;
import com.xiaoq.push.service.PushMessageService;
import com.xiaoq.qiniu.QiNiuSpaceEnum;
import com.xiaoq.qiniu.UploadUtil;
import com.xiaoq.social.service.IFollowService;
import com.xiaoq.users.entity.UserEntity;
import com.xiaoq.users.entity.UserEntity.Role;
import com.xiaoq.users.entity.UserPhoneEntity;
import com.xiaoq.users.entity.UserTermDeviceEntity;
import com.xiaoq.users.redis.RedisTemplate4JedisCluster;
import com.xiaoq.users.service.*;
import com.xiaoq.users.service.exception.AuthenFailException;
import com.xiaoq.users.service.exception.UserAlreadyExistException;
import com.xiaoq.users.service.exception.UserNotFoundException;
import com.xiaoq.users.service.exception.UsersErrorCode;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;

/**
 * 
 * @author wang zhihao  created at 2017/11/24
 *
 */
@RestController
@RequestMapping(value = "/api/v1/user")
@Api(tags={"用户相关Api"})
class AccountEndpoint {

	private static Logger logger = LoggerFactory.getLogger(AccountEndpoint.class);
	private static final class VCodeResponse extends GenericDataResponse<VCodeVo>{};
	private static final class AccountInfoResponse extends GenericDataResponse<AccountInfoVo>{};
	private class LogoDataResponse extends GenericDataResponse<String>{}
	private class UnionIdDataResponse extends GenericDataResponse<MiniUniResponse> {}
	@Autowired
	private AccountService accountServcie;

	@Autowired
	private OAuth2Service oAuth2Service;

	@Autowired
	private VerificationCodeService verificationCodeService;
	
	@Autowired
	private IFollowService followSer;
	
	@Autowired
	private IdGenerator idGenerator;
	
	@Autowired
	private MiniProService miniProSer;

	@Autowired
	private UserPhoneService userPhoneService;
	
	@Autowired
	private RedisTemplate4JedisCluster redisTemplate;

	
	@Reference(interfaceClass=IUserCouponApi.class,check=false,version="1.0.0")
	private IUserCouponApi couponDubboApi;
	
	@Reference(interfaceClass=IInterpreterApi.class,check=false,version="1.0.0")
	private IInterpreterApi interpreterDubboApi;
	
	@Autowired
    PushMessageService pushMessageService;
	
	@ApiOperation(value = "获取图形验证码", notes = "获取图形验证码")
	@ApiResponses({ @ApiResponse(code = 200, message = "图形验证码", response = VCodeResponse.class)})
	@GetMapping(value = "/vcode", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<?> getVCode() {
		VCodeVo vo = verificationCodeService.createVCode();
		return GenericDataResponse.okWithData(vo);
	}
	
	@ApiOperation(value = "手机号注册", notes = "手机号注册")
	@ApiResponses({ @ApiResponse(code = 200, message = "注册结果", responseHeaders = {
			@ResponseHeader(name = "access_token", response = String.class),
			@ResponseHeader(name = "refresh_token", response = String.class)}, response = AccountInfoResponse.class),
		@ApiResponse(code=400, message="手机号、密码、验证码都不能为空"),
		@ApiResponse(code=403, message="短信验证码不正确或已超时"),
		@ApiResponse(code=409, message="手机号已经存在")})
	@RequestMapping(value = "/reg_by_mobile", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
	public ResponseEntity<?> registerByCellphoneNumber(@RequestBody LoginVo loginVo) {
		String mobile = loginVo.getMobile();
		String passwd = loginVo.getPasswd();
		String smsCode = loginVo.getSmsCode();
		UserEntity userInDB;
		if (StringUtils.isAnyBlank(mobile, passwd, smsCode)) {
			return GenericResponse.ng("手机号、密码、短信验证码都不能为空");
		}

		// TODO 须增加手机号、密码格式校验逻辑？
		
		boolean isVerified = verificationCodeService.verifyVerificationCode(mobile, smsCode);
		if (!isVerified) {
			return GenericResponse.ng("短信验证码不正确");
		}
		try {
			UserEntity entity = new UserEntity();
			BeanUtils.copyProperties(loginVo, entity);
			entity.setNickName(idGenerator.nextId());
			entity.setAccount(mobile);
			entity.setMobileValid(true);
			userInDB = accountServcie.createByCellphoneNumber(entity);
		} catch (UserAlreadyExistException uae) {
			return GenericResponse.ng("该手机号已经存在 请直接登录");
		}
		String userId = userInDB.getId();

		/**     添加用户手机归属地 信息 begin     */
		try {
			UserPhoneEntity userPhoneEntity = new UserPhoneEntity();
			userPhoneEntity.setId(idGenerator.nextId());
			userPhoneEntity.setUserId(userId);
			userPhoneEntity.setMobile(userInDB.getMobile());
			userPhoneService.save(userPhoneEntity);
		}catch (Exception e){
			logger.error("添加用户的电话归属地失败:{}", e.getMessage());
		}
		/**     添加用户手机归属地 信息 end      */

		Integer durToken = loginVo.getDurToken();
		HttpHeaders httpHeaders = null;
		if(durToken!=null&&durToken!=0){
			httpHeaders = setToken4HttpHeadersByDays(userInDB.getId(),durToken);
		}else{
			httpHeaders = setToken4HttpHeaders(String.valueOf(userInDB.getId()));
		}
		String osType = loginVo.getTermDevice().getOsType();
		if(osType.equals("Android")||osType.equals("iOS")){
			pushMessageService.sendMessageToXiaomi(userId, "1", "我们为你准备了新手礼包", "欢迎使用小Q旅行，我们为你量身打造天气服务，规划游览路线，查询最近吃玩乐信息等服务，让出游更简单！",null,"1",null,null,false);
		}
		AccountInfoVo accVo = new AccountInfoVo();
		BeanUtils.copyProperties(userInDB, accVo);
		return AccountInfoResponse.okWithData(accVo, httpHeaders);

	}

	
	@ApiOperation(value = "第三方登录", notes = "第三方登录")
	@ApiResponses({ @ApiResponse(code = 200, message = "登录结果", responseHeaders = {
			@ResponseHeader(name = "access_token", response = String.class),
			@ResponseHeader(name = "refresh_token", response = String.class)}, response = AccountInfoResponse.class) })
	@RequestMapping(value = "/login_by_third_acc", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
	public ResponseEntity<?> loginByThirdAppAccount(@RequestBody ThirdLoginVo thirdLoginVo) {
		UserEntity userInDB;
		UserEntity userEntity = null;
		try {
			userInDB = accountServcie.loginByThirdOpenId(thirdLoginVo);
			HttpHeaders httpHeaders = setToken4HttpHeaders(String.valueOf(userInDB.getId()));
			AccountInfoVo accVo = new AccountInfoVo();
			BeanUtils.copyProperties(userInDB, accVo);
			return AccountInfoResponse.okWithData(accVo, httpHeaders);
		} catch (AuthenFailException unex) {
			userEntity = new UserEntity();
			AccountInfoVo accVo = new AccountInfoVo();
			accVo.setRegister_step(1);
            return AccountInfoResponse.okWithData(accVo);
		}

	}
	@ApiOperation(value = "第三方登录第二步", notes = "第三方登录第二步")
	@ApiResponses({ @ApiResponse(code = 200, message = "登录结果第二步", responseHeaders = {
			@ResponseHeader(name = "access_token", response = String.class),
			@ResponseHeader(name = "refresh_token", response = String.class)}, response = AccountInfoResponse.class) })
	@RequestMapping(value = "/register_by_third_acc", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
	 public ResponseEntity<?> updateAccountInfoFromThirdAPPAndBindingCellphone(@RequestBody ThirdRegisterVo thirdRegisterVo) {
		
		String mobile = thirdRegisterVo.getMobile();
		String smsCode = thirdRegisterVo.getSmsCode();
		UserEntity responseUserEntity;
		if (StringUtils.isAnyBlank(mobile,smsCode)) {
			return GenericResponse.ng("手机号、短信验证码都不能为空");
		}
		boolean isVerified = verificationCodeService.verifyVerificationCode(mobile, smsCode);
		if (!isVerified) {
			return GenericResponse.ng("短信验证码不正确或已超时");
		}else{
			//userEntity.setName(userEntity.getThirdAccount());
			responseUserEntity = accountServcie.registerOrBindingCellphoneByThirdOpenId(thirdRegisterVo);
			String userId = responseUserEntity.getId();

			/**     添加用户手机归属地 信息 begin     */
			try {
				UserPhoneEntity userPhoneEntity = new UserPhoneEntity();
				userPhoneEntity.setId(idGenerator.nextId());
				userPhoneEntity.setUserId(userId);
				userPhoneEntity.setMobile(mobile);
				userPhoneService.save(userPhoneEntity);
			}catch (Exception e){
				logger.error("第三方登录第二步, 添加用户的电话归属地失败:{}", e.getMessage());
			}
			/**     添加用户手机归属地 信息 end     */

			UserTermDeviceEntity terDevice = thirdRegisterVo.getTermDevice();
			if(terDevice==null){
				return GenericResponse.ng("设备信息不能为空！");
			}
			String osType = terDevice.getOsType();
			if(osType.equals("Android")||osType.equals("iOS")){
				pushMessageService.sendMessageToXiaomi(userId, "1", "我们为你准备了新手礼包", "欢迎使用小Q旅行，我们为你量身打造天气服务，规划游览路线，查询最近吃玩乐信息等服务，让出游更简单！",null,"1",null,null,false);
			}
			HttpHeaders httpHeaders = setToken4HttpHeaders(String.valueOf(responseUserEntity.getId()));
			AccountInfoVo accVo = new AccountInfoVo();
			BeanUtils.copyProperties(responseUserEntity, accVo);
			accVo.setRegister_step(2);
			return AccountInfoResponse.okWithData(accVo, httpHeaders);

		}
		
	 }


	@ApiOperation(value = "匿名登录", notes = "匿名登录")
	@ApiResponses({ @ApiResponse(code = 200, message = "登录结果", responseHeaders = {
			@ResponseHeader(name = "access_token", response = String.class),
			@ResponseHeader(name = "refresh_token", response = String.class) },response = AccountInfoResponse.class)})
	@RequestMapping(value = "/anonymous", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
	public ResponseEntity<?> anonymous(@RequestBody UserTermDeviceEntity term) {
		String imei = term.getMobileImei();
		if (StringUtils.isBlank(imei)) {
			return GenericResponse.ng("非法请求，缺少终端信息");
		}
		UserEntity userInDB;
		try {
			userInDB = accountServcie.loginByTerm(term);
		} catch (RegisterUserCannotAnonymousException ex) {
			throw new RestException(HttpStatus.BAD_REQUEST, ex.getMessage(), UsersErrorCode.REGISTER_USER_CANNOT_ANONYMOUS_LOGIN.value);
		}
		HttpHeaders httpHeaders = setAnonymousToken4HttpHeaders(userInDB.getId());
		AccountInfoVo accVo = new AccountInfoVo();
		BeanUtils.copyProperties(userInDB, accVo);
		return AccountInfoResponse.okWithData(accVo, httpHeaders);

	}
	
	@ApiOperation(value = "手机号+密码登录", notes = "手机号+密码登录")
	@ApiResponses({ @ApiResponse(code = 200, message = "登录结果", responseHeaders = {
			@ResponseHeader(name = "access_token", response = String.class),
			@ResponseHeader(name = "refresh_token", response = String.class) },response = AccountInfoResponse.class),
		@ApiResponse(code=400, message="手机号、密码、验证码都不能为空"),
		@ApiResponse(code=401, message="手机号或密码错误"),
		@ApiResponse(code=403, message="验证码不正确或已超时")})
	@RequestMapping(value = "/login_by_passwd", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
	public ResponseEntity<?> loginByCellphoneNumberAndPassword(@RequestBody LoginVo loginVo) {
		String mobile = loginVo.getMobile();
		String errNum = redisTemplate.get("user.vCodeErr", mobile);
		int errNums = 0;
		if(errNum!=null){
			errNums = Integer.parseInt(errNum);
		}
		if(errNums>5){
			VCodeVo vCodeVo = loginVo.getvCode();
			if (vCodeVo == null || StringUtils.isAnyBlank(loginVo.getMobile(), loginVo.getPasswd(), vCodeVo.getKey(), vCodeVo.getCode())) {
				return GenericResponse.ngWithCode("手机号或者密码不能为空！", "9998");
			}
			boolean isVerified = verificationCodeService.verifyVCode(vCodeVo.getKey(), vCodeVo.getCode());
			if (!isVerified) {
				return GenericResponse.ngWithCode("验证码输入不正确！", "9998");
			}
		}
		
		
		// TODO 须增加手机号、密码格式校验逻辑？
		// TODO 这里不需要添加一个手机号和短信验证码的逻辑
		
		// 1、执行登录
		UserEntity userInDB;
		
		try {
			userInDB = accountServcie.loginByMobileAndPasswd(mobile, loginVo.getPasswd(), loginVo.getTermDevice());
		} catch (AuthenFailException ex) {
			
			errNums = errNums+1;
			redisTemplate.setWithExpireTime("user.vCodeErr", mobile, errNums+"",3600*24);
			if(errNums>5){
				return GenericResponse.ngWithCode("手机号或者密码错误", "9998");
			}
			return GenericResponse.ng("手机号或者密码错误");
		}
		redisTemplate.setWithExpireTime("user.vCodeErr", mobile, 0+"",3600*24);
		Integer durToken = loginVo.getDurToken();
		HttpHeaders httpHeaders = null;
		if(durToken!=null&&durToken!=0){
			httpHeaders = setToken4HttpHeadersByDays(userInDB.getId(),durToken);
		}else{
			httpHeaders = setToken4HttpHeaders(String.valueOf(userInDB.getId()));
		}
		AccountInfoVo accVo = new AccountInfoVo();
		BeanUtils.copyProperties(userInDB, accVo);
		return AccountInfoResponse.okWithData(accVo, httpHeaders);

	}

	@ApiOperation(value = "手机号+短信验证码登录", notes = "手机号+短信验证码登录")
	@ApiResponses({ @ApiResponse(code = 200, message = "登录结果", responseHeaders = {
			@ResponseHeader(name = "access_token", response = String.class),
			@ResponseHeader(name = "refresh_token", response = String.class) }, response = AccountInfoResponse.class),
		@ApiResponse(code=400, message="手机号、验证码都不能为空"),
		@ApiResponse(code=401, message="该手机号未注册"),
		@ApiResponse(code=403, message="短信验证码不正确或已超时")})
	@RequestMapping(value = "/login_by_smscode", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
	public ResponseEntity<?> loginByCellphoneNumberAndVerificationCode(@RequestBody LoginVo loginVo) {

		if (StringUtils.isAnyBlank(loginVo.getMobile(), loginVo.getSmsCode())) {
			throw new RestException(HttpStatus.BAD_REQUEST, "手机号、短信验证码都不能为空");
		}
		
		// TODO 须增加手机号、密码格式校验逻辑？
		
		boolean isVerified = verificationCodeService.verifyVerificationCode(loginVo.getMobile(), loginVo.getSmsCode());
		if (!isVerified) {
			throw new RestException(HttpStatus.FORBIDDEN, "短信验证码不正确或已超时");
		}
		// 1、执行登录
		UserEntity userInDB;
		try {
			userInDB = accountServcie.loginByMobileAndSmsCode(loginVo.getMobile(), loginVo.getSmsCode(), loginVo.getIp());
		} catch (AuthenFailException une) {
			throw new RestException(HttpStatus.UNAUTHORIZED, "该手机号未注册");
		}
		// 2、为用户生成access_token与refresh_token
		HttpHeaders httpHeaders = setToken4HttpHeaders(userInDB.getId());
		AccountInfoVo accVo = new AccountInfoVo();
		BeanUtils.copyProperties(userInDB, accVo);
		return AccountInfoResponse.okWithData(accVo, httpHeaders);

	}
	
	@ApiOperation(value = "查询用户信息", notes = "查询用户信息")
	@ApiResponses({ @ApiResponse(code = 200, message = "查询结果", response = AccountInfoResponse.class)})
	@GetMapping(value = "/info/{userId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<?> getUserInfo(@PathVariable(value = "userId", required = false)@ApiParam(value="userId",required=false)String userId) {
		UserEntity userInDB = accountServcie.getById(userId);
		if (userInDB == null) {
			return GenericResponse.ng("查不到数据");
		}
		AccountInfoVo accVo = new AccountInfoVo();
		BeanUtils.copyProperties(userInDB, accVo);
		List<Role> roleList = accVo.getUserRoleList();
		
		//如果是讲解员多返回两条信息
		if(roleList.contains(Role.INTERPRETER)){
			Long confirmCount= 0L;
			try{
			confirmCount = interpreterDubboApi.getInterWaitConfirmCount(userId);
			}catch(Exception e){
				logger.error("查询讲解员确认总数出问题！", e);
			}
			accVo.setConfirmCount(confirmCount);
			//TODO  这里需要调用一个根据userId查询待结束数
			Long stopCount = 0L;
			accVo.setStopCount(stopCount);
			
		}
		
		Long followCount = followSer.findFollowNumsByUser(userId);
		accVo.setFollowCount(followCount);
		Long couponCount = 0L;
		try{
		couponCount = couponDubboApi.getUserCouponCount(userId);
		}catch(Exception e){
			logger.error("查询优惠卷总数出问题！", e);
		}
		accVo.setCouponCount(couponCount);
		
		return AccountInfoResponse.okWithData(accVo);

	}

	
	@ApiOperation(value = "修改手机号", notes = "修改手机号")
	@ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "修改手机号") })
	@PostMapping(value = "/{userId}/mobile", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> changeMobile(
			@PathVariable(value = "userId", required = false)@ApiParam(value="userId",required=false)String userId,
			@RequestParam(value="mobile",required=true)String mobile,
			@RequestParam(value="vCode",required=true)String vCode){
		// 1、验证用户输入的验证码是否是服务器端刚刚发送给TA的验证码（由于此处仅仅是做一个验证,是一个无状态的操作,因此无需放入Service层)
				boolean isVerified = verificationCodeService.verifyVerificationCode(mobile, vCode);
				if (!isVerified) {
					return GenericResponse.ng("验证码错误或已过期");
				} else {// 2、如果短信或语音验证码验证通过,则修改密码
					UserEntity userInMobile = accountServcie.findByMobile(mobile);
					if(userInMobile!=null){
						return GenericResponse.ng("新手机号已经被注册不能被修改，请您更换手机号！！！");
					}
					try {
						UserEntity user = new UserEntity();
						user.setId(userId);
						user.setMobile(mobile);
						accountServcie.updateUser(user);
					} catch (UserNotFoundException e) {
						return GenericResponse.ng(e.getMessage());
					}

					/**     添加用户手机归属地 信息 begin     */
					try {
						UserPhoneEntity userPhoneEntity = new UserPhoneEntity();
						userPhoneEntity.setId(idGenerator.nextId());
						userPhoneEntity.setUserId(userId);
						userPhoneEntity.setMobile(mobile);
						userPhoneService.save(userPhoneEntity);
					}catch (Exception e){
						logger.error("添加用户的电话归属地失败:{}", e.getMessage());
					}
					/**     添加用户手机归属地 信息 end      */

					return GenericResponse.ok();
				}
	
	}
	
	
	@ApiOperation(value = "小程序获取unionId", notes = "小程序获取unionId")
	@ApiResponses({ @ApiResponse(code = 200, message = "小程序获取unionId", response = UnionIdDataResponse.class)})
	@GetMapping(value = "/miniUid", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public ResponseEntity<?> getUnionid(
			@RequestParam(value = "shopId",required = true) @ApiParam (value = "就是写在动态配置里面的景区Id",required = true)String shopId,
			@RequestParam(value = "code", required = false)@ApiParam(value="code",required=false)String code) {
		MiniUniResponse miniUniResponse = miniProSer.getUidByCode(code,shopId);
		if(miniUniResponse==null){
			return GenericResponse.ng("获取小程序UnionId 出错！");
		}
			
		String errCode = miniUniResponse.getErrcode();
		if(errCode!=null){
			String errMessage = miniUniResponse.getErrmsg();
			logger.error("获取小程序报错信息！错误码："+errCode+"错误信息："+errMessage);
			return GenericResponse.ng(errMessage);
		}
		
		String unionId = miniUniResponse.getUnionid();
		if(StringUtils.isEmpty(unionId)){
			unionId = miniUniResponse.getOpenid();
		}
		miniUniResponse.setUnionid(unionId);
		String session_key = miniUniResponse.getSession_key();
		redisTemplate.set(ConstantUtil.WEIXINUNIONID_SESSIONKEY, unionId, session_key);
		
		
		return UnionIdDataResponse.okWithData(miniUniResponse);

	}
	
	@ApiOperation(value = "修改密码", notes = "修改密码")
	@ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "修改密码") })
	@PostMapping(value = "/{userId}/passwd", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> changePasswd(
			@PathVariable(value = "userId", required = false)@ApiParam(value="userId",required=false)String userId,
			@RequestParam(value="passwd",required=true)String passwd){
		UserEntity user = accountServcie.changePassword(userId, passwd);
		if(user!=null){
			String password = user.getPasswd();
			return GenericDataResponse.okWithData(password);
		}else{
			return GenericResponse.ng("修改密码失败！");
		}
		
	}
	
	@ApiOperation(value = "重置密码", notes = "重置密码")
	@ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "重置密码") })
	@PostMapping(value = "/mobile/passwd", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> changePasswdByPhone(
			@RequestParam(value = "mobile", required = true)@ApiParam(value="mobile",required=true)String mobile,
			@RequestParam(value="passwd",required=false)@ApiParam(value="passwd",required=false)String passwd,
			@RequestParam(value="vCode",required=true)String vCode){
		boolean isVerified = verificationCodeService.verifyVerificationCode(mobile, vCode);
		if (!isVerified) {
			return GenericResponse.ng("验证码错误或已过期");
		}
		if(StringUtils.isNotEmpty(passwd)){
			boolean result = false;
			try {
				result = accountServcie.passwordByMobil(passwd, mobile);
			} catch (Exception e) {
				return GenericResponse.ng(e.getMessage());
			}
			if(result){
				return GenericResponse.ok();
			}else{
				return GenericResponse.ng("重置密码失败！");
			}
		}else{
			return GenericResponse.ok();
		}
		
		
	}
	
	@ApiOperation(value = "修改昵称", notes = "修改昵称")
	@ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "修改昵称") })
	@PostMapping(value = "/{userId}/nickName", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> changeNickName(
			@PathVariable(value = "userId", required = false)@ApiParam(value="userId",required=false)String userId,
			@RequestParam(value="nickName",required=true)String nickName){
		UserEntity user = new UserEntity();
		user.setId(userId);
		user.setNickName(nickName);
		boolean result = accountServcie.updateUser(user);
		if(result){
			return GenericResponse.ok();
		}else{
			return GenericResponse.ng("修改昵称失败！");
		}
		
	}
	
	@ApiOperation(value = "点击获取短信验证码", notes = "点击获取短信验证码")
	@ApiResponses({ @ApiResponse(code = 200, response = String.class, message = "点击获取短信验证码") })
	@PostMapping(value = "/verCode", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> getVerificationCode(@RequestParam(value="phoneNum",required=true)@ApiParam(value="手机号",required=true)String phoneNum,@ModelAttribute VCodeVo vCode) {
		String verCodeNum = redisTemplate.get("user.verCodeErr", phoneNum);
		int verCodeNums = 0;
		if(verCodeNum!=null){
			verCodeNums=Integer.parseInt(verCodeNum);;
		}
		if(verCodeNums<=10){
			redisTemplate.setWithExpireTime("user.verCodeErr",phoneNum, verCodeNums+1+"", 3600*24);
			verificationCodeService.createAndSendVerificationCode(phoneNum);
			return GenericResponse.ok();
		}else{
			return GenericResponse.ng("短信验证码一日内发送了指定的次数10次请24小时后发送");
		}
//		if(vCode!=null){
//			boolean isVerified = verificationCodeService.verifyVCode(vCode.getKey(), vCode.getCode());
//			if (!isVerified) {
//				throw new RestException(HttpStatus.FORBIDDEN, "验证码不正确或已超时");
//			}
//		}else{
			// 产品没有确定先不校验验证码
//			throw new RestException(HttpStatus.BAD_REQUEST, "验证码不能为空");
//		}
		
	}
	
	@ApiOperation(value = "修改LOGO", notes = "修改LOGO")
	@ApiResponses({ @ApiResponse(code = 200, response = LogoDataResponse.class, message = "修改LOGO") })
	@PostMapping(value = "/{userId}/logo", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> changeLogo(
			@PathVariable(value = "userId", required = false)@ApiParam(value="userId",required=false)String userId,
			@RequestParam(value="file") MultipartFile file){
		String imgUrl = null;
		try {
			
			//TODO 上传七牛云的图片有大小限制处理一下
			imgUrl = UploadUtil.easyUploadByte(file,
			        QiNiuSpaceEnum.XIAOQ_USER.getName().toLowerCase(), QiNiuSpaceEnum.XIAOQ_USER.getDomain());
			logger.info("上传七牛云的图片地址："+imgUrl);
			UserEntity user = new UserEntity();
			user.setId(userId);
			user.setLogoUrl(imgUrl);
			boolean result = accountServcie.updateUser(user);
			if(result){
				return LogoDataResponse.okWithData(imgUrl);
			}else{
				return GenericResponse.ng("修改logo失败！");
			}
			
		} catch (IOException e) {
			logger.error("七牛云上传的流出现问题！", e);
			return GenericResponse.ng("修改logo失败！");
		}
		
	}
	
	
	
	/*
	 * 用户登出
	 */
	@RequestMapping(value = "/logout", method = RequestMethod.POST)
	public ResponseEntity logout(HttpServletRequest request) {
		Long userId = Long.parseLong((String) request.getAttribute("userId"));
		accountServcie.logout(userId);
		return new ResponseEntity(null, HttpStatus.OK);
	}

	@RequestMapping(value = "generateToken4test", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.GET)
	public HttpHeaders generateToken4test(@RequestParam String userId) {
		// 为用户生成access_token与refresh_token,手机端进行缓存,进入信息完善页面时,可以利用access_token与refresh_token进行用户信息更新
		OAuth2TokenEntity oAuth2Token = oAuth2Service.getAccessTokenAndRefreshToken4XiaoqAPP(userId,
				"lifestyle365-secret-201611120-20191119", 365);

		String bearerAccessToken = "Bearer " + oAuth2Token.getAccessToken();
		String refreshToken = oAuth2Token.getRefreshToken();

		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.set("access_token", bearerAccessToken);
		httpHeaders.set("refresh_token", refreshToken);

		logger.info("bearer access_token : " + bearerAccessToken);
		logger.info("refresh_token : " + refreshToken);
		return httpHeaders;
	}

	private HttpHeaders setToken4HttpHeadersByDays(String userId,int durToken) {
		// 为用户生成access_token与refresh_token,手机端进行缓存,进入信息完善页面时,可以利用access_token与refresh_token进行用户信息更新
		OAuth2TokenEntity oAuth2Token = oAuth2Service.getAccessTokenAndRefreshToken4XiaoqAPP(userId,
				"lifestyle365-secret-201611120-20191119", durToken);
		String bearerAccessToken = "Bearer " + oAuth2Token.getAccessToken();
		String refreshToken = oAuth2Token.getRefreshToken();

		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.set("access_token", bearerAccessToken);
		httpHeaders.set("refresh_token", refreshToken);

		logger.info("bearer access_token : " + bearerAccessToken);
		logger.info("refresh_token : " + refreshToken);
		return httpHeaders;
	}
	private HttpHeaders setToken4HttpHeaders(String userId) {
		// 为用户生成access_token与refresh_token,手机端进行缓存,进入信息完善页面时,可以利用access_token与refresh_token进行用户信息更新
		OAuth2TokenEntity oAuth2Token = oAuth2Service.getAccessTokenAndRefreshToken4XiaoqAPP(userId,
				"lifestyle365-secret-201611120-20221119", 365);
		String bearerAccessToken = "Bearer " + oAuth2Token.getAccessToken();
		String refreshToken = oAuth2Token.getRefreshToken();

		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.set("access_token", bearerAccessToken);
		httpHeaders.set("refresh_token", refreshToken);

		logger.info("bearer access_token : " + bearerAccessToken);
		logger.info("refresh_token : " + refreshToken);
		return httpHeaders;
	}
	
	private HttpHeaders setAnonymousToken4HttpHeaders(String userId) {
		// 为用户生成access_token与refresh_token,手机端进行缓存,进入信息完善页面时,可以利用access_token与refresh_token进行用户信息更新
		OAuth2TokenEntity oAuth2Token = oAuth2Service.getAnonymousAccessTokenAndRefreshToken4XiaoqAPP(userId,
				"lifestyle365-secret-201611120-20221119", 365);
		String bearerAccessToken = "Bearer " + oAuth2Token.getAccessToken();
		String refreshToken = oAuth2Token.getRefreshToken();

		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.set("access_token", bearerAccessToken);
		httpHeaders.set("refresh_token", refreshToken);

		logger.info("bearer access_token : " + bearerAccessToken);
		logger.info("refresh_token : " + refreshToken);
		return httpHeaders;
	}

}
